<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title th:text="${activityStruct.displayName} + '-进度预览'"></title>
    <link href="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/css/bootstrap.min.css" rel="stylesheet">
    <style>
        :root {
            --node-width: 320px;
            --primary-color: #4a90e2;
            --running-gradient: linear-gradient(135deg, #ff6b6b 0%, #ff9f43 100%);
            --progress-gradient: linear-gradient(45deg, #4a90e2 25%, #6c5ce7 100%);
        }

        body {
            font-family: 'Arial', sans-serif;
            background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
            min-height: 100vh;
            padding: 40px 20px;
        }

        /* 主流程容器 */
        .main-flow {
            display: flex;
            flex-direction: column;
            align-items: center;
            position: relative;
            padding: 0 20px;
        }

        /* 并行分支容器 */
        .parallel-section {
            display: flex;
            justify-content: center;
            gap: 30px;
            margin: 30px 0;
            position: relative;
        }

        /* 并行分支列 */
        .parallel-column {
            background: rgba(255, 255, 255, 0.9);
            border-radius: 16px;
            padding: 25px;
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
            border: 1px solid rgba(255, 255, 255, 0.3);
            min-width: var(--node-width);
            backdrop-filter: blur(10px);
            position: relative;
        }

        /* 任务节点 */
        .node {
            width: var(--node-width);
            min-height: 90px;
            background: rgba(255, 255, 255, 0.95);
            border-radius: 12px;
            padding: 18px;
            margin: 18px 0;
            box-shadow: 0 4px 20px rgba(0, 0, 0, 0.08);
            /*transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);*/
            position: relative;
            overflow: hidden;
            border: 1px solid rgba(0, 0, 0, 0.05);

            /* 新增悬浮光效 */
            transition: transform 0.3s ease, box-shadow 0.3s ease;
        }

        .node::before {
            content: '';
            position: absolute;
            top: -50%;
            left: -50%;
            width: 200%;
            height: 200%;
            background: var(--running-gradient);
            opacity: 0;
            transition: opacity 0.3s;
            z-index: 0;
        }

        .node:hover {
            transform: translateY(-5px) scale(1.02);
            box-shadow: 0 0 30px rgba(74, 144, 226, 0.5);
        }

        /* 运行中状态特效 */
        .status-running {
            position: relative;
            animation: nodePulse 2s infinite;
        }

        .status-running::after {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            border-radius: 12px;
            animation: borderGlow 2s infinite;
            pointer-events: none;
        }

        /* 进度条样式 */
        .progress-container {
            position: relative;
            height: 12px;
            background: rgba(0, 0, 0, 0.05);
            border-radius: 6px;
            overflow: hidden;
            margin-top: 15px;
        }

        .progress-bar {
            height: 100%;
            background: var(--progress-gradient);
            position: relative;
            transition: width 0.5s ease-out;
        }

        .progress-bar::after {
            content: '';
            position: absolute;
            top: 0;
            left: 0;
            right: 0;
            bottom: 0;
            background: linear-gradient(90deg,
            transparent 25%,
            rgba(255, 255, 255, 0.3) 50%,
            transparent 75%);
            animation: progressShine 1.5s infinite;
        }

        /* 连接线样式 */
        .flow-line {
            position: absolute;
            background: var(--primary-color);
            opacity: 0.3;
            z-index: -1;
        }

        .vertical-line {
            width: 2px;
            height: 40px;
            left: 50%;
        }

        .branch-connector {
            height: 2px;
            width: 60px;
            top: 50%;
        }

        /* 合并点样式 */
        .merge-point {
            width: 24px;
            height: 24px;
            background: var(--primary-color);
            border-radius: 50%;
            margin: 40px auto;
            position: relative;
            box-shadow: 0 0 20px rgba(74, 144, 226, 0.3);
            animation: mergePulse 2s infinite;
        }

        /* 动画定义 */
        @keyframes nodePulse {
            0% {
                box-shadow: 0 0 0 0 rgba(255, 107, 107, 0.4);
            }
            70% {
                box-shadow: 0 0 0 12px rgba(255, 107, 107, 0);
            }
            100% {
                box-shadow: 0 0 0 0 rgba(255, 107, 107, 0);
            }
        }

        @keyframes borderGlow {
            0% {
                box-shadow: inset 0 0 12px rgba(255, 107, 107, 0.3);
            }
            50% {
                box-shadow: inset 0 0 20px rgba(255, 107, 107, 0.5);
            }
            100% {
                box-shadow: inset 0 0 12px rgba(255, 107, 107, 0.3);
            }
        }

        @keyframes progressShine {
            0% {
                transform: translateX(-100%);
            }
            100% {
                transform: translateX(100%);
            }
        }

        @keyframes mergePulse {
            0% {
                transform: scale(0.95);
                opacity: 0.8;
            }
            50% {
                transform: scale(1.05);
                opacity: 1;
            }
            100% {
                transform: scale(0.95);
                opacity: 0.8;
            }
        }

        /* 状态标签 */
        .status-badge {
            font-size: 0.8em;
            padding: 6px 14px;
            border-radius: 20px;
            background: rgba(0, 0, 0, 0.08);
            color: #2c3e50;
            display: inline-block;
            margin-top: 10px;
            backdrop-filter: blur(4px);
            border: 1px solid rgba(0, 0, 0, 0.05);
        }

        .status-running .status-badge {
            background: rgba(255, 107, 107, 0.15);
            color: #d63031;
            animation: badgePulse 1.5s infinite;
        }

        .status-completed {
            background: rgba(120, 255, 120, 0.15);
            color: #d63031;
        }

        @keyframes badgePulse {
            0% {
                opacity: 0.8;
                transform: scale(1);
            }
            50% {
                opacity: 1;
                transform: scale(1.05);
            }
            100% {
                opacity: 0.8;
                transform: scale(1);
            }
        }

        /* 图标动画 */
        .node-icon {
            font-size: 1.2em;
            margin-right: 8px;
            display: inline-block;
        }

        .status-running .node-icon {
            animation: iconFloat 1.5s ease-in-out infinite;
        }

        @keyframes iconFloat {
            0%, 100% {
                transform: translateY(0);
            }
            50% {
                transform: translateY(-5px);
            }
        }

        /* 炫酷庆祝特效 */
        .confetti {
            position: absolute;
            width: 10px;
            height: 10px;
            background-color: #ff6b6b;
            border-radius: 50%;
            animation: confettiAnimation 2s ease-out forwards;
        }

        @keyframes confettiAnimation {
            0% {
                opacity: 1;
                transform: translateY(0) rotate(0deg);
            }
            100% {
                opacity: 0;
                transform: translateY(-100vh) rotate(360deg);
            }
        }

        /* 新增响应式设计 */
        @media (max-width: 768px) {
            :root {
                --node-width: 90%;
            }

            .parallel-section {
                gap: 20px;
            }

            .node {
                margin: 12px 0;
            }
        }
    </style>
</head>
<body>

<div class="container">
    <h1 class="text-center mb-5 display-5 fw-bold" style="color: #2c3e50;">
        <span style="background: linear-gradient(135deg, #4a90e2, #6c5ce7); -webkit-background-clip: text; color: transparent;"
              th:text="${activityStruct.displayName} + '-进度预览'">
        </span>
    </h1>

    <div style="display: none" id="activityId" th:text="${activityStruct.id}"></div>
    <div style="display: none" id="progressId" th:text="${progressId}"></div>
    <div style="display: none" id="endStepName" th:text="${activityStruct.endStepId}"></div>

    <div th:each="activityBlockList : ${activityStruct.progressBlocks}">
        <div th:class="${activityBlockList.type eq 'SERIAL' ? 'main-flow' : 'parallel-section'}">
            <div th:if="${activityBlockList.type eq 'PARALLEL'}" class="parallel-column"
                 th:each="parallelActivityList : ${activityBlockList.list}">

                <div th:each="parallelColumnList : ${parallelActivityList}">
                    <div th:each="activity : ${parallelColumnList}" class="node status-waiting" th:id="${activity.id}">
                        <div class="node-header">
                            <span class="node-icon" th:text="${activity.icon}"></span><span
                                th:text="${activity.title}"></span>
                        </div>
                        <span class="status-badge">等待开始</span>
                        <div class="progress-container" style="display:none">
                            <div class="progress-bar" style="width: 1%"></div>
                        </div>
                    </div>

                </div>
            </div>
            <div th:if="${activityBlockList.type eq 'SERIAL'}" class="node status-waiting"
                 th:each="activity : ${activityBlockList.list}" th:id="${activity.id}">
                <div class="node-header">
                    <span class="node-icon" th:text="${activity.icon}"></span><span th:text="${activity.title}"></span>
                </div>
                <span class="status-badge">等待开始</span>
                <div class="progress-container" style="display:none">
                    <div class="progress-bar" style="width: 1%"></div>
                </div>

            </div>
        </div>
    </div>

</div>

<script th:inline="javascript">
    const urlParams = new URLSearchParams(window.location.search);
    const progressId = urlParams.get('progressId');
    const activityId = urlParams.get('activityId');
    const endStepName = document.getElementById('endStepName').textContent;

    if (!progressId) {
        alert('请输入正确的progressId');
    } else {
        const intervalId = setInterval(fetchProgress, 500);

        function fetchProgress() {
            fetch(`/api/v1/activities/progress?progressId=${progressId}&activityId=${activityId}`)
                .then(response => response.json())
                .then(data => updateProgress(data, intervalId))
                .catch(error => console.error('Error fetching progress:', error));
        }

        function updateProgress(data, intervalId) {
            for (const [taskKey, taskData] of Object.entries(data)) {
                const node = document.getElementById(taskKey);
                if (node) {
                    const badge = node.querySelector('.status-badge');
                    const progressBarContainer = node.querySelector('.progress-container');
                    const progressBar = node.querySelector('.progress-bar');
                    let costText = convertCostToText(taskData.timeConsumed);
                    let leftTimeText = convertCostToText(taskData.timeLeft);
                    switch (taskData.status) {
                        case 0: // WAITING
                            node.className = 'node status-waiting';
                            badge.textContent = '等待开始';
                            if (progressBarContainer) {
                                progressBarContainer.style.display = 'none';
                            }
                            break;
                        case 1: // RUNNING
                            node.className = 'node status-running';
                            badge.textContent = `执行中（${Math.round(taskData.processed / taskData.totalNum * 100)}%），预计还需 ${leftTimeText}`;
                            if (progressBarContainer) {
                                progressBarContainer.style.display = 'block';
                            }
                            if (progressBar) {
                                progressBar.style.width = `${Math.round(taskData.processed / taskData.totalNum * 100)}%`;
                            }
                            break;
                        case 2: // EXCEPTION
                            node.className = 'node status-exception';
                            badge.textContent = `异常终止，耗时 ${costText}`;
                            alert('生成 SLA 报告出现异常，请检查日志！异常节点：' + taskKey);
                            clearInterval(intervalId);
                            break;
                        case 3: // FINISHED
                            if (node.id === endStepName) {
                                // 最后一个任务完成，停止定时查询
                                clearInterval(intervalId);
                                triggerConfetti();
                            }
                            node.className = 'node status-completed';
                            badge.textContent = `✅ 已完成，耗时 ${costText}`;
                            if (progressBarContainer) {
                                progressBarContainer.style.display = 'none';
                            }
                            break;
                        default:
                            badge.textContent = '未知状态';
                            if (progressBarContainer) {
                                progressBarContainer.style.display = 'none';
                            }
                    }
                }
            }

        }

        function triggerConfetti() {
            const confettiCount = 100;
            for (let i = 0; i < confettiCount; i++) {
                const confetti = document.createElement('div');
                confetti.classList.add('confetti');
                confetti.style.left = `${Math.random() * 100}vw`;
                confetti.style.animationDelay = `${Math.random() * 2}s`;
                confetti.style.backgroundColor = `hsl(${Math.random() * 360}, 100%, 50%)`;
                document.body.appendChild(confetti);

                // Remove confetti after animation
                confetti.addEventListener('animationend', () => {
                    confetti.remove();
                });
            }
        }

        function convertCostToText(cost) {
            if (cost <= 20) {
                return '一眨眼';
            } else if (cost > 20 && cost <= 1000) {
                return `${cost.toFixed(0)} ms`;
            } else if (cost > 1000 && cost <= 100000) {
                return `${(cost / 1000).toFixed(1)} s`;
            } else {
                return '未知';
            }
        }
    }
</script>
<script src="https://cdn.bootcdn.net/ajax/libs/twitter-bootstrap/5.3.0/js/bootstrap.bundle.min.js"></script>
</body>
</html>